package com.horizon.common.configuration;

import com.horizon.common.event.AuditLogEvent;
import com.horizon.common.util.SpringUtil;
import org.hibernate.boot.Metadata;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.*;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.springframework.stereotype.Component;

/**
 * Hibernate监听器，发布审计日志
 *
 * @author wangfuwei
 * @version 2018-08-08
 */
@Component
public class HibernateListener implements Integrator, PostCommitInsertEventListener, PostCommitDeleteEventListener, PostCommitUpdateEventListener {

    @Override
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
        eventListenerRegistry.prependListeners(EventType.POST_COMMIT_INSERT, this);
        eventListenerRegistry.prependListeners(EventType.POST_COMMIT_DELETE, this);
        eventListenerRegistry.prependListeners(EventType.POST_COMMIT_UPDATE, this);
    }

    @Override
    public void onPostUpdate(PostUpdateEvent event) {
        if (SpringUtil.getProperty("horizon.log.audit", boolean.class, false)) {
            SpringUtil.publishEvent(new AuditLogEvent(this, event));
        }
    }

    @Override
    public void onPostDelete(PostDeleteEvent event) {
        if (SpringUtil.getProperty("horizon.log.audit", boolean.class, false)) {
            SpringUtil.publishEvent(new AuditLogEvent(this, event));
        }
    }

    @Override
    public void onPostInsert(PostInsertEvent event) {
        if (SpringUtil.getProperty("horizon.log.audit", boolean.class, false)) {
            SpringUtil.publishEvent(new AuditLogEvent(this, event));
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean requiresPostCommitHanding(EntityPersister persister) {
        return true;
    }

    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {

    }

    @Override
    public void onPostDeleteCommitFailed(PostDeleteEvent event) {

    }

    @Override
    public void onPostInsertCommitFailed(PostInsertEvent event) {

    }

    @Override
    public void onPostUpdateCommitFailed(PostUpdateEvent event) {

    }
}
